package com.jerei.plugin.dao.impl;

import com.jerei.utils.condition.ConditionEntity;
import com.jerei.utils.condition.ConditionTools;
import com.jerei.utils.condition.SQLEntity;
import com.jerei.utils.spring.PageBean;
import com.jerei.plugin.dao.I${entityName}Dao;
import com.jerei.plugin.entity.${entityName};
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import com.jerei.plugin.utils.JrJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.beans.factory.annotation.Autowired;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

/**
 * Created by sunfeihu on 2016/10/20.
 */
@Repository
public class ${entityName}DaoImpl implements I${entityName}Dao {

    @Autowired
private JrJdbcTemplate jrJdbcTemplate;

    @Override
    public ${entityName} save(${entityName} entity) {
        final String sql = " insert into ${tableName} (${insertField}) values(${insertQField})";
        KeyHolder keyHolder = new GeneratedKeyHolder();
        final ${entityName} finalEntity = entity;
        this.jrJdbcTemplate.getJdbcTemplate().update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
                <#list fieldsNoId as field>
                    <#if field.dataType=='datetime'>
                    if (null != finalEntity.get${field.getSetName}()) {
                        ps.setObject(${field_index+1}, new java.sql.Timestamp(finalEntity.get${field.getSetName}().getTime()));
                    }else{
                        ps.setObject(${field_index+1}, null);
                    }
                    <#else>
                        ps.setObject(${field_index+1}, finalEntity.get${field.getSetName}());
                    </#if>
                </#list>
                return ps;
            }
        }, keyHolder);
        Long id = keyHolder.getKey().longValue();
        return this.find(id);
    }

    @Override
    public int delete(Long id) {
        final String sql = " delete from ${tableName} where id = ? ";
        return this.jrJdbcTemplate.getJdbcTemplate().update(sql, new Object[]{
                id
        });
    }

    @Override
    public int update(${entityName} entity) {
        final String sql = " update ${tableName} set ${updateField} where id = ?";
        return this.jrJdbcTemplate.getJdbcTemplate().update(sql, new Object[]{
        <#list fieldsNoId as field>
            entity.get${field.getSetName}(),
        </#list>
            entity.getId()
        });
    }

    @Override
    public ${entityName} find(Long id) {
        final String sql = " select * from ${tableName} where id = ? ";
        return this.jrJdbcTemplate.getJdbcTemplate().queryForObject(sql,new Object [] {id}, new ${entityName}RowerMapper());
    }

    @Override
    public void save(List<${entityName}> list) {
        if (null != list && list.size() > 0) {
            final String sql = " insert into ${tableName} (${insertField}) values(${insertQField})";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            ${entityName} entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[${fieldsNoId?size}];
                <#list fieldsNoId as field>
                    objArr[${field_index}] = entity.get${field.getSetName}();
                </#list>
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void delete(List<Long> ids) {
        if (null != ids && ids.size() > 0) {
            final String sql = " delete from ${tableName} where id = ? ";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            for (int i = 0; i < ids.size(); i++) {
                objArr = new Object[1];
                objArr[0] = ids.get(i);
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public void update(List<${entityName}> list) {
        if (null != list && list.size() > 0) {
            final String sql = " update ${tableName} set ${updateField} where id = ?";
            List<Object[]> params = new ArrayList<Object[]>();
            Object[] objArr = null;
            ${entityName} entity = null;
            for (int i = 0; i < list.size(); i++) {
                entity = list.get(i);
                objArr = new Object[${fieldsNoId?size}];
                <#list fieldsNoId as field>
                    objArr[${field_index}] = entity.get${field.getSetName}();
                </#list>
                objArr[${fieldsNoId?size}] = entity.getId();
                params.add(objArr);
            }
            this.jrJdbcTemplate.getJdbcTemplate().batchUpdate(sql, params);
        }
    }

    @Override
    public PageBean<${entityName}> page(int nowPage, int pageSize ,ConditionEntity conditionEntity) {
        SQLEntity sqlEntity = ConditionTools.conditionEntities2SQL(conditionEntity);
        final String sql = " select * from ${tableName} where 1 = 1 " + sqlEntity.getSql() + " order by " + sqlEntity.getOrder();
        return new PageBean<${entityName}>(sql, sqlEntity.getParams(), nowPage, pageSize, new ${entityName}RowerMapper(), this.jrJdbcTemplate.getJdbcTemplate());
    }
}


class ${entityName}RowerMapper implements RowMapper<${entityName}>{
    @Override
    public ${entityName} mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        Set<String> fieldSet = new HashSet<String>();
        for (int i = 1; i <= columnCount; i++) {
            fieldSet.add(rsmd.getColumnName(i));
        }
        ${entityName} entity = new ${entityName}();
        <#list fields as field>
            if(fieldSet.contains("${field.dbColumnName}") && null != rs.getObject("${field.dbColumnName}")){
            <#if field.dataType=='datetime'>
                entity.set${field.getSetName}(new java.util.Date(rs.getTimestamp("${field.dbColumnName}").getTime()));
            <#else>
                entity.set${field.getSetName}(rs.get${field.mapperType}("${field.dbColumnName}"));
            </#if>
            }
        </#list>
        return entity;
    }
}